#include <iostream>
#include <unistd.h>
#include <cstring>
#include <cassert>
#include <pthread.h>

using namespace std;








// // 添加 __thread  可以将一个内置类型设置为线程的局部存储。
// //虽然还是全局变量，但是在编译的时候给每一个线程都来一份，各玩各的了。
// __thread int number = 100;

// void* fun(void* agv)
// {
//     sleep(1);
//     while(1)
//     {
//         cout<<"new thread runing..... ：    "<<"number: "<<number <<" &number: "<<&number<<endl;
//         number++;
//         sleep(5);
//     }
//     return nullptr;
// }



// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, fun, nullptr);
//     while(true)
//     {
//         cout<<"main thread runing.... ：    "<<"number: "<<number <<" &number: "<<&number<<endl;
//         sleep(2);
//     }

//     return 0;
// }

// void* fun(void* agv)
// {
//     char buf[64];
//     snprintf(buf, sizeof(buf), "0x%x",pthread_self());//把tid转为十六进制。
//     while(true)
//     {
//         cout<<"new thread runing...."<<"new thread tid:"<<buf<<endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid ;
//     pthread_create(&tid, nullptr, fun, nullptr);
//     char buf[64];
//     snprintf(buf, sizeof(buf), "0x%x",tid);//把tid转为十六进制。
//     while(true)
//     {
//         cout<<"main thread runing..."<<"new thread tid:"<<buf<<endl;
//         sleep(1);
//     }
//     return 0;
// }

// void * fun(void * s)
// {
//     string str = static_cast<const char*>(s);
//     //static_cast 安全的类型转化，不能转化的就报错了。
//     //pthread_detach(pthread_self());
//     //自己把自己设置为分离状态。
//     int cnt = 5;
//     while(cnt--)
//     {
//         cout<<str<<"runing....."<<endl;
//         sleep(1);
//     }

//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr,fun, (void*)"thread 1");
//     assert(0 == n);

//     pthread_detach(tid);
//     //主线程把新线程设置为分离状态。

//     // int ret = pthread_join(tid, nullptr);
//     // cout<<"ret:"<<ret<<":"<<strerror(ret)<<endl;
//     //线程创建的时候默认是joinable状态的，如果设置分离状态，就不能进行pthread_join等待了。
//     //如果设置了分离状态还去用join等待它，就会报错。
//     //ret:22:Invalid argument

//     while(true)
//     {
//         cout<<"main, runing....."<<endl;
//         sleep(2);
//     }
//     return 0;
// }

// #include<iostream>
// #include<unistd.h>
// #include<thread>//c++的头文件

// void thread_run()
// {
//     while(true)
//     {
//         std::cout<<"我是新线程......"<<std::endl;
//         sleep(1);
//     }
// }
// int main()
// {
//     std::thread t1(thread_run);
//     while(true)
//     {
//         std::cout<<"我是主线程......"<<std::endl;
//         sleep(1);
//     }
//     t1.join();
//     return 0;
// }

// // #include<iostream>
// // #include<pthread.h>
// // #include<cassert>
// // #include<string>
// // #include<unistd.h>
// // #include<iostream>
// // #include<vector>

// // using namespace std;
// // #define NUM 10

// // struct ThreadData{
// //     pthread_t tid;
// //     char namebuf[64];
// // };

// // void* mythread_coutine(void * agv)
// // {
// //     sleep(1);
// //     string str = static_cast<ThreadData*>(agv)->namebuf;
// //     int cnt =5;
// //     while(cnt--)
// //     {
// //         cout<<"这是新线程，"<<str<<endl;
// //         sleep(1);
// //     }
// //     return (void*)100;
// //     //正常退出的时候会返回：100
// //     //但是线程被取消的时候，不是100。
// // }

// // int main()
// // {
// //     vector<ThreadData*> ptds;
// //     for(int i =0 ;i<NUM;i++)
// //     {
// //         ThreadData* td = new ThreadData();
// //         snprintf(td->namebuf, sizeof(td->namebuf),"编号是：%d", i);
// //         int ret = pthread_create(&(td->tid),nullptr, mythread_coutine, (void*)td);
// //         ptds.push_back(td);
// //     }

// //     //创建的新线程会跑6秒后退出
// //     //我们在3秒的时候给所有线程发送取消信号。
// //     sleep(3);
// //     //取消一半的线程。
// //     for(int i =0 ; i< ptds.size()/2; i++)
// //     {
// //         pthread_cancel(ptds[i]->tid);
// //         cout<<"pthread_cancel ： "<<ptds[i]->namebuf<<endl;
// //     }
// //     for(auto e : ptds)
// //     {
// //         void* n = nullptr;
// //         int ret = pthread_join(e->tid, &n);//阻塞式等待。
// //         assert( 0 == ret);
// //         cout<<"join: "<<e->namebuf<<" success" << "取出返回信息："<<(long long)n<<endl;
// //         delete e;
// //         (void)ret;
// //     }
// //     cout<<"main thread join succsess"<<endl;
// //     return 0;
// // }

// // // int main()
// // // {
// // //     void* pp = nullptr;
// // //     cout<<sizeof pp <<endl;

// // //     return 0;
// // // }

// // // struct ThreadData{
// // //     pthread_t tid;
// // //     char namebuf[64];
// // // };
// // // void* mythread_coutine(void * agv)
// // // {
// // //     sleep(1);
// // //     string str = static_cast<ThreadData*>(agv)->namebuf;
// // //     int cnt =5;
// // //     while(cnt--)
// // //     {
// // //         cout<<"这是新线程，"<<str<<endl;
// // //         sleep(1);
// // //     }

// // //     //return (void*)((char*)agv+sizeof(pthread_t));
// // //     //return (void*)(((ThreadData*)agv)->namebuf);
// // //     //返回对应的线程name。
// // //     //pthread_exit((void*)(((ThreadData*)agv)->namebuf));

// // //     //return (void*)22L;
// // //     //return (void*)(long long)22;
// // //     long long * ret = new long long(22);
// // //     return (void*)ret;

// // // }

// // // int main()
// // // {
// // //     vector<ThreadData*> ptds;
// // //     for(int i =0 ;i<NUM;i++)
// // //     {
// // //         ThreadData* td = new ThreadData();
// // //         //每一次开辟的空间地址是不同的。
// // //         snprintf(td->namebuf, sizeof(td->namebuf),"编号是：%d", i);
// // //         int ret = pthread_create(&(td->tid),nullptr, mythread_coutine, (void*)td);
// // //         ptds.push_back(td);
// // //         //sleep(1);
// // //     }

// // //     for(auto e : ptds)
// // //     {
// // //         // char* buf;
// // //         // int ret = pthread_join(e->tid, (void**)(&buf));//阻塞式等待。

// // //         //ThreadData* td = new ThreadData();
// // //         //int ret = pthread_join(e->tid, (void**) (&td));//阻塞式等待。

// // //         // void* n = nullptr;
// // //         // int ret = pthread_join(e->tid, &n);//阻塞式等待。

// // //         void* n = nullptr;
// // //         int ret = pthread_join(e->tid, &n);//阻塞式等待。

// // //         assert( 0 == ret);
// // //         //cout<<"join: "<<e->namebuf<<" success" << "取出返回信息："<<buf<<endl;
// // //         //cout<<"join: "<<e->namebuf<<" success" << "取出返回信息："<<(char*)td->namebuf<<endl;
// // //         cout<<"join: "<<e->namebuf<<" success" << "取出返回信息："<<*(long long*)n<<endl;
// // //         delete (long long *)n;
// // //         delete e;
// // //         (void)ret;
// // //     }

// // //     cout<<"main thread join succsess"<<endl;
// // //     return 0;
// // // }

// // // string fun()
// // // {
// // //     return string("这是一个独立的方法！！");
// // // }
// // //这个函数会给新的线程去调用
// // // void* mythread_coutine(void * agv)
// // // {
// // //     while(true)
// // //     {
// // //         cout<<"我是新线程，name："<<(char*)agv<<fun()<<endl;
// // //         sleep(1);
// // //     }
// // //     return nullptr;
// // // }
// // // struct ThreadData{
// // //     pthread_t tid;
// // //     char namebuf[64];
// // // };

// // // void* mythread_coutine(void * agv)
// // // {
// // //     sleep(1);
// // //     //string str = (char*)agv;
// // //     string str = static_cast<ThreadData*>(agv)->namebuf;
// // //     //安全的进行强制类型转换。
// // //     int cnt =10;
// // //     while(cnt--)
// // //     {
// // //         cout<<"这是新线程，"<<str<<endl;
// // //         sleep(1);

// // //         // char* p = nullptr;
// // //         // *p = '0';
// // //         // //如果一个线程出问题也会影响其他线程，这就是多线程的健壮性或者鲁棒性较差。
// // //         // //信号是整体发送给进程的，多线程只有一个进程pid。全部会受到信号退出。
// // //     }
// // //    //delete agv;
// // //    //一般在等待线程之后再释放。
// // //     return nullptr;
// // //     //线程终止可以直接以return的方式进行终止。
// // //     //线程函数走到return的时候就算是终止了。

// // //     //exit(1);
// // //     //exit不能用来终止线程，他是用来终止进程的。
// // //     //在任何一个执行流里面调用exit函数都会让整个进程全部终止。

// // //     pthread_exit(nullptr);
// // //     //这pthread库里面的调用接口。和return 几乎相同。
// // // }

// // // int main()
// // // {
// // //     vector<ThreadData*> ptds;
// // //     for(int i =0 ;i<NUM;i++)
// // //     {
// // //         ThreadData* td = new ThreadData();
// // //         //每一次开辟的空间地址是不同的。
// // //         snprintf(td->namebuf, sizeof(td->namebuf),"编号是：%d", i);
// // //         int ret = pthread_create(&(td->tid),nullptr, mythread_coutine, (void*)td);
// // //         ptds.push_back(td);
// // //         //sleep(1);
// // //     }

// // //     for(auto e : ptds)
// // //     {
// // //         int ret = pthread_join(e->tid, nullptr);//阻塞式等待。
// // //         assert( 0 == ret);
// // //         cout<<"join: "<<e->namebuf<<"success"<<endl;
// // //         delete e;
// // //         (void)ret;
// // //     }

// // //     cout<<"main thread join succsess"<<endl;

// // //     // while(true)
// // //     // {
// // //     //     cout<<"主线程，正在执行！！"<<endl;
// // //     //     sleep(1);
// // //     // }
// // //     return 0;
// // // }